home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Shareware Overload Trio 2
/
Shareware Overload Trio Volume 2 (Chestnut CD-ROM).ISO
/
dir31
/
in_out.zip
/
PORT-IN.OUT
< prev
Wrap
Text File
|
1993-01-16
|
15KB
|
347 lines
╔════════════════════════════════════════════════════════════════════════════╗
║ The - INs ORs ANDs OUTs - of creating sound on the IBM PC ║
║ ║
║ by William Cravener 520 N. Stateline Rd. Sharon, Pa. 16146 ║
║ ║
║ »-Swift-Ware-> Copyright 1991-93 CIS: 72230,1306 ║
╚════════════════════════════════════════════════════════════════════════════╝
There are two important electronic chips involved in creating sound
on the IBM PC - the 8253 timer chip (channel 2 of this chip is connected to
the speaker), and the 8255 peripheral interface chip (it appears regardless
of what peripheral interface chip is used in any particular machine, the same
port address and bit assignments are used). The pulse rate of each chip can
be altered, and by combining the actions of the two chips it is possible to
produce special sound effects.
To make sounds on the IBM PC you must actually turn ON and OFF an
electronic "gate" (which is a kind of toggle switch). Each time we toggle the
"gate" ON and OFF again, we create a pulse: a brief period when current flows
in a circuit (look at the example below). These pulses are amplified and sent
to the speaker, where they make a sound. This "gate" is turned ON and OFF
with the assembly OUT instruction.
One
Pulse
| |
+ ┌─────┐ ┌─────┐ ┌─────┐
│ │ │ │ │ │
0 ────┘ └─────┘ └─────┘ └──── <-- Wave form sent to the Speaker.
| |
| "gate"
| is turned OFF here
"gate"
is turned ON here
The faster we send the pulses, the higher the pitch of the sound. We
can control how fast we send the pulses by putting a delay loop into our
program. We then turn the "gate" ON, delay, turn the "gate" OFF, delay, and
so on and so on. The assembly LOOP instruction is used to cause the delay that
we will need for our example sound program.
But, before we go on to the example program lets talk a little about
addressing the PORTs (I/O Ports). Ports are something like registers, in
that you can send 8-bit or 16-bit data to them. This is always accomplished
using the AL or AX register, you can also read the port contents back into
the AL or AX register. The big difference between ports and registers is that
ports can be connected to devices either inside or outside of your computer.
How then, do you access these I/O Ports??? Well, its not that
difficult once you acquire a little understanding about how to send information
to these ports using a few very simple assembly language instructions.
The two most important instructions you will be using are the assembly
IN and OUT instructions. The IN instruction places a byte of information into
the AL or AX register, the OUT instruction copies a byte or word of information
from the AL or AX register.
The instruction that turns our "gate" ON and OFF is:
OUT 61H, AL
This instruction copies the contents of the AL register to the port 61H.
This port addresses the 8255 or equivalent programmable peripheral
interface chip or PPI. The PPI is used to control the keyboard, the speaker
and the computer configuration settings.
OUT is very much like the assembly MOV instruction, but instead of
moving information to a register we copy it from a register to a port address
as in the above example (port address 61H).
Now in the case of creating sound we need to be concerned with two of
the 8-bits we send to port address 61H. These are the bits numbered 0 and 1.
8-bit number --> 11111111
The two we are interested in -> 111111XX
(marked as X's) ||___ bit number 0
|____ bit number 1
In order to change bits 0 and 1 (without changing the other 6 bits),
we need to find out how all the bits are initially set. This is easily done
by using the assembly IN instruction to retreive this value. Once we know how
all 8-bits are initially set, we can change the first two (0 and 1) then copy
the value back to the port address 61H.
IN AL, 61H
This instruction copies the current 8-bit value of port 61H to the AL register.
Once we have this 8-bit value we need to change bits 0 and 1 so we
can send the changed ON or OFF value back OUT to our port address. This is a
two part procedure, first we wish to turn the speaker ON so we OR the 8-bit
value with a value of our own that will not change the upper 6-bits, the
assembly OR instruction accomplishes this:
OR AL, 00000011B ;<- More often then not programmers show
| ; this OR or AND value as a binary number.
|
|____ The letter "B" simply tells the assembler
that this group of numbers is a binary value.
The unknown value we get from port 61H ---> 101010 00 <- ( IN AL, 61H )
Then we first OR it with this value ------> 000000 11 <-Our ORing ON value -
this value will enable
the speaker.
Leaves all bits except 0 and 1 unchanged -> 101010 11 <-The resulting value -
|| bits 0 and 1 have both
bit 1__|| been forced to values
bit 0___| of - 1 (ON)
Now we want to return this altered number back OUT to port 61H to
turn ON the speaker. This is easily accomplished by using the above explained
assembly OUT instruction in the following manner.
OUT 61H, AL ;<-- copy the value in the AL register to Port 61H
At this point the computers speaker will sound until a new binary
value is sent back OUT to port 61H to turn the speaker OFF.
Here is the complete code to turn ON the speaker:
IN AL, 61H ;Get current value of port 61H.
OR AL, 00000011B ;OR AL to this value, forcing first two bits high.
OUT 61H, AL ;Copy it to port 61H of the PPI chip.
Here is where our next assembly instruction needs to enter the picture
to turn the speaker OFF. That instruction is the AND instruction, kind of like
the opposite of the OR instruction. As with turning ON the speaker we must use
a similar procedure to turn the speaker OFF.
First get unknown value from port 61H ----> 101010 11 <- ( IN AL, 61H )
Then we first AND it with this value -----> 111111 00 <-Our ANDing OFF value -
(This 8-bit number is the exact opposite this value will disable
of our OR value above). the speaker.
Leaves all bits except 0 and 1 unchanged -> 101010 00 <-The resulting value -
|| bits 0 and 1 have both
bit 1__|| been forced to values
bit 0___| of - 0 (OFF)
Here is the complete code to turn OFF the speaker:
IN AL,61H ;Get current value of port 61H.
AND AL,11111100B ;AND AL to this value, forcing first two bits low.
OUT 61H,AL ;Copy it to port 61H of the PPI chip.
Ok, now if you think about it if we were to turn the speaker ON with:
IN AL, 61H
OR AL, 00000011B
OUT 61H, AL
And then, directly turn the speaker back OFF with:
IN AL, 61H
AND AL, 11111100B
OUT 61H, AL
You wouldn't hear a thing (except maybe a click), it all happens to
fast. We need to cause some kind of delay between the two procedures. We do
this by setting up a LOOP instruction between our two procedures. This is
done by putting a value in the CX register and executing the assembly LOOP
instruction.
Here is an example of its use:
MOV CX, 100 ;Repeat the loop 100 times
DELAY_LOOP: ;We loop back to here
LOOP DELAY_LOOP ;Jump repeatedly to DELAY_LOOP until CX = 0
This will sound the speaker for a Duration of 100 repeated Loops.
Here is the Whole Noisy Routine:
IN AL,61H ;Get current value of port 61H.
OR AL,00000011B ;OR AL to this value, forcing first two bits high.
OUT 61H,AL ;Copy it to port 61H of the PPI chip.
MOV CX,100 ;Repeat the loop 100 times
DELAY_LOOP: ;We loop back to here
LOOP DELAY_LOOP ;Jump repeatedly to DELAY_LOOP until CX = 0
IN AL,61H ;Get current value of port 61H.
AND AL,11111100B ;AND AL to this value, forcing first two bits low.
OUT 61H,AL ;Copy it to port 61H of the PPI chip.
This is a very good method of creating beeps and boops, but we what
to get a little more involved then this and create more interesting sound
effects. We could create many different sounds if we were to include help
from the computers timer chip. This is the 8253 programmable timer and has
the ability to enable a certain action at a certain point in time. It senses
timing from oscillations it recieves from the PC's 8284 oscillator chip, which
generates 1,193,180 pulses per second. The 8253 chip can then be instructed
how many of these pulses it should wait for before triggering a certain action.
In the case of tone generation, this action consists of sending a pulse to the
speaker. Before executing this action, the 8253 chip must be programmed for a
particular frequency it should generate.
There are actually three different timers built into the computer.
Timer 0 is used in DMA data transfer (Direct Memory Access), Timer 1 is used
as a system clock oscillator (18.2 times per second), and the one we are
interested in Timer 2 which is connected to the computers speaker.
Using the Timer to generate sound is a little more complicated than
simply sending pulses to the speaker. There are three steps envolved in using
this method of sound creation.
Step 1. Copy a certain number to Timer 2 to initialize it.
Step 2. Copy a 16 bit number to Timer 2 to establish the frequency
of the tone to be generated.
Step 3. Turn on the speaker to enable the frequency adjusted sound
to be heard.
You access Timer 2 thru two port addresses, the first is used to
initialize (make it ready to receive data) thru port 43H, you then send a
16-bit value in two 8-bit steps. First, the Least Significant Byte (LSB)
is copied to port address 42H, second, the Most Significant Byte (MSB) is
copied to port address 42H. A 16-bit value is called a WORD, a WORD value
is made up of two BYTES, LSB and MSB.
_______________ ____ (WORD)
| |
16-bit binary value -> 00000000 00000001
| | |______|____ (BYTE) LSB
| |
|______|_____________ (BYTE) MSB
Here is how all this is accomplished:
MOV BX, 1 ; Frequency Value.
; Formula = 1,193,180 \ frequency value
; Will put it in BX for now.
; The lower the value the higher
; the sound / the higher the value
; the lower the sound.
MOV AL, 10110110B ; The Magic Number (use this binary number only!)
OUT 43H, AL ; Send it to the initializing port 43H Timer 2.
MOV AX, BX ; Move our Frequency Value into AX.
OUT 42H, AL ; Send LSB to port 42H.
MOV AL, AH ; Move MSB into AL
OUT 42H, AL ; Send MSB to port 42H.
IN AL, 61H ; Get current value of port 61H.
OR AL, 00000011B ; OR AL to this value, forcing first two bits high.
OUT 61H, AL ; Copy it to port 61H of the PPI Chip
; to turn ON the speaker.
MOV CX, 100 ; Repeat the loop 100 times.
DELAY_LOOP: ; We loop back to here.
LOOP DELAY_LOOP ; Jump repeatedly to DELAY_LOOP until CX = 0
IN AL, 61H ; Get current value of port 61H.
AND AL, 11111100B ; AND AL to this value, forcing first two bits low.
OUT 61H, AL ; Copy it to port 61H of the PPI Chip
; to turn OFF the speaker.
Next we need to make our sound maker more interesting. To do this
we will simply use a method of repeating the whole thing a specified number
of times and also increment the frequency value to create a sound that drops
in frequency. To accomplish this we will use the assembly JMP instruction
and also at the same time, increment our frequency value.
Here is a complete example:
MOV DX,2000 ; Number of times to repeat whole routine.
MOV BX,1 ; Frequency value.
MOV AL, 10110110B ; The Magic Number (use this binary number only)
OUT 43H, AL ; Send it to the initializing port 43H Timer 2.
NEXT_FREQUENCY: ; This is were we will jump back to 2000 times.
MOV AX, BX ; Move our Frequency value into AX.
OUT 42H, AL ; Send LSB to port 42H.
MOV AL, AH ; Move MSB into AL
OUT 42H, AL ; Send MSB to port 42H.
IN AL, 61H ; Get current value of port 61H.
OR AL, 00000011B ; OR AL to this value, forcing first two bits high.
OUT 61H, AL ; Copy it to port 61H of the PPI Chip
; to turn ON the speaker.
MOV CX, 100 ; Repeat loop 100 times
DELAY_LOOP: ; Here is where we loop back too.
LOOP DELAY_LOOP ; Jump repeatedly to DELAY_LOOP until CX = 0
INC BX ; Incrementing the value of BX lowers
; the frequency each time we repeat the
; whole routine
DEC DX ; Decrement repeat routine count
CMP DX, 0 ; Is DX (repeat count) = to 0
JNZ NEXT_FREQUENCY ; If not jump to NEXT_FREQUENCY
; and do whole routine again.
; Else DX = 0 time to turn speaker OFF
IN AL,61H ; Get current value of port 61H.
AND AL,11111100B ; AND AL to this value, forcing first two bits low.
OUT 61H,AL ; Copy it to port 61H of the PPI Chip
; to turn OFF the speaker.
In conclusion, with the included examples and a little imagination, there is no
limit to the sound effects that are possible to create.
Included examples are:
PHASOR.ASM
FONETONE.ASM
Have Fun !!
================================================================================